﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

/**
*@file       protonet.cs
*@brief      protobuf helper
*
*@author     graywind
*@version    1.0.0.0
*@data       2012/02/13
*/


public class ProtoNet<proto_type> where proto_type : new()
{
    #region external call
    /// <summary>
    /// read from bytes
    /// </summary>
    /// <param name="msg_buffer"></param>
    /// <param name="msg_bytes"></param>
    /// <returns></returns>
    public static proto_type CreateFromBytes(byte[] msg_buffer, UInt32 msg_bytes)
    {
        using (System.IO.Stream stream = new System.IO.MemoryStream(msg_buffer, 0, (int)msg_bytes))
        {
            proto_type p = ProtoBuf.Serializer.Deserialize<proto_type>(stream);
            return p;
        }
    }

    /// <summary>
    /// broadcast message to all session
    /// </summary>
    /// <param name="message_type"></param>
    /// <param name="p"></param>
    public static int Broadcast(uint message_type, proto_type p, NetLib.eUsageType type)
    {
        byte[] stream = IntoBytes(p);
        return NetLib.broadcast_msg(message_type, (uint)stream.Length, Marshal.UnsafeAddrOfPinnedArrayElement(stream, 0), type);
    }

    /// <summary>
    /// send a message to server
    /// </summary>
    /// <param name="session_id"></param>
    /// <param name="message_type"></param>
    /// <param name="p"></param>
    public static bool Send(int session_id, uint message_type, proto_type p)
    {
        byte[] stream = IntoBytes(p);
        return NetLib.send_msg(session_id, message_type, (uint)stream.Length, Marshal.UnsafeAddrOfPinnedArrayElement(stream, 0));
    }

    /// <summary>
    /// convert into bytes
    /// </summary>
    /// <param name="p"></param>
    /// <returns></returns>
    public static byte[] IntoBytes(proto_type p)
    {
        using (System.IO.MemoryStream stream = new System.IO.MemoryStream())
        {
            ProtoBuf.Serializer.Serialize<proto_type>(stream, p);
            return stream.ToArray();
        }
    }
    #endregion
}

public class ProtoNet
{
    /// <summary>
    /// broadcast a message to all session
    /// </summary>
    /// <param name="message_type"></param>
    /// <returns></returns>
    public static int Broadcast(uint message_type, NetLib.eUsageType type)
    {
        return NetLib.broadcast_msg(message_type, type);
    }

    /// <summary>
    /// send a message to server
    /// </summary>
    /// <param name="session_index"></param>
    /// <param name="message_type"></param>
    /// <returns></returns>
    public static bool Send(int session_index, uint message_type)
    {
        return NetLib.send_msg(session_index, message_type);
    }
}